package so.wy.servicecenter.businessbed.service.statics;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import so.wy.servicecenter.base.frame.service.AbstractService;
import so.wy.servicecenter.businessbed.dao.rdb.hospital.hospital.HospitalDAO;
import so.wy.servicecenter.businessbed.dao.rdb.hospital.hospital.HospitalDO;
import so.wy.servicecenter.businessbed.dao.rdb.hospital.hospital_building.HospitalBuildingDAO;
import so.wy.servicecenter.businessbed.dao.rdb.hospital.hospital_building.HospitalBuildingDO;
import so.wy.servicecenter.businessbed.dao.rdb.hospital.hospital_depart.HospitalDepartDAO;
import so.wy.servicecenter.businessbed.dao.rdb.hospital.hospital_depart.HospitalDepartDO;
import so.wy.servicecenter.businessbed.dao.rdb.statics.*;
import so.wy.servicecenter.businessbed.service.statics.dto.ItemOrderDeviceStaticsDTO;
import so.wy.servicecenter.businessbed.service.statics.dto.TodayStaticsDTO;
import so.wy.servicecenter.businessbed.service.statics.dto.TotalStaticsDTO;

import java.util.ArrayList;
import java.util.List;

@Service
@Scope("prototype")
public class BedStaticsService extends AbstractService {
    @Autowired
    private HospitalDAO hospitalDAO;

    @Autowired
    private StaticsDAO staticsDAO;

    @Autowired
    private HospitalBuildingDAO buildingDAO;

    @Autowired
    private HospitalDepartDAO departDAO;

    //1、总订单量
    //2、总订单金额，总实际支付金额，总免单金额
    //3、当前押金池金额 当前总充值用户数
    //4、总床数量 总投放床数量
    public TotalStaticsDTO getTotalStatics() {
        TotalStaticsDTO staticsDTO = new TotalStaticsDTO();
        staticsDTO.setTotalOrderCount(staticsDAO.totalOrderCount());
        staticsDTO.setTotalOrderFee(staticsDAO.totalOrderFee());
        staticsDTO.setTotalOrderPayFee(staticsDAO.totalOrderFee());
        staticsDTO.setTotalOrderFreeFee(staticsDAO.totalOrderFreeFee());
        staticsDTO.setTotalDespoistFee(staticsDAO.totalYjFee());
        staticsDTO.setTotalCzUserCount(staticsDAO.totalYjUserCount());
        staticsDTO.setTotalDeviceCount(staticsDAO.totalDeviceCount());
        staticsDTO.setTotalDeviceTfCount(staticsDAO.totalDeviceTfCount());

        return staticsDTO;
    }

    //医院总信息
    public List<ItemOrderDeviceStaticsDTO> getTotalHospitalInfo() {
        return mergeHospitalOrderDeviceInfo(staticsDAO.totalOrderInfoGroupHospital(),
                staticsDAO.totalDeviceInfoGroupHospital());
    }

    //最近一个月总订单量变化趋势
    public List<OrderLineStaticsDO> totalDayOrderCountLineLastMonth() {
        return staticsDAO.totalDayOrderCountLineLastMonth();
    }

    //7、充值用户变化趋势
    public List<UserLineStaticsDO> totalCzUserCountLine() {
        return staticsDAO.totalCzUserCountLine();
    }

    //统计当天的一些信息
    public TodayStaticsDTO getTodayInfo() {
        TodayStaticsDTO todayStatics = new TodayStaticsDTO();
        todayStatics.setTodayOrderCount(staticsDAO.todayOrderCount());
        todayStatics.setTodayOrderFee(staticsDAO.todayOrderFee());
        todayStatics.setTodayOrderPayFee(staticsDAO.todayOrderPayFee());
        todayStatics.setTodayOrderFreeFee(staticsDAO.todayOrderFreeFee());
        todayStatics.setTodayDespoistFee(staticsDAO.todayCzAmount());
        todayStatics.setTodayCzUserCount(staticsDAO.todayCzUserCount());

        return todayStatics;
    }

    //4、医院当日订单信息（总订单量，订单金额，实际支付金额）
    public List<OrderWdStaticsDO> todayOrderInfoGroupHospital() {
        return staticsDAO.todayOrderInfoGroupHospital();
    }

    //医院维度
    public TotalStaticsDTO getTotalHospitalStatics(Long hospitalId) {
        TotalStaticsDTO staticsDTO = new TotalStaticsDTO();
        staticsDTO.setTotalOrderCount(staticsDAO.totalOrderCountByHospital(hospitalId));
        staticsDTO.setTotalOrderFee(staticsDAO.totalOrderFeeByHospital(hospitalId));
        staticsDTO.setTotalOrderPayFee(staticsDAO.totalOrderFeeByHospital(hospitalId));
        staticsDTO.setTotalOrderFreeFee(staticsDAO.totalOrderFreeFeeByHospital(hospitalId));
        staticsDTO.setTotalDeviceTfCount(staticsDAO.totalDeviceTfCountByHospital(hospitalId));

        return staticsDTO;
    }

    //统计当天的一些信息
    public TodayStaticsDTO getTodayHospitalInfo(Long hospitalId) {
        TodayStaticsDTO todayStatics = new TodayStaticsDTO();
        todayStatics.setTodayOrderCount(staticsDAO.todayOrderCountByHospital(hospitalId));
        todayStatics.setTodayOrderFee(staticsDAO.todayOrderFeeByHospital(hospitalId));
        todayStatics.setTodayOrderPayFee(staticsDAO.todayOrderPayFeeByHospital(hospitalId));
        todayStatics.setTodayOrderFreeFee(staticsDAO.todayOrderFreeFeeByHospital(hospitalId));

        return todayStatics;
    }

    //2、各楼层 投放床数量 总订单量
    public List<ItemOrderDeviceStaticsDTO> getTotalFloorInfo(Long hospitalId) {
        return mergeFloorOrderDeviceInfo(hospitalId, staticsDAO.totalOrderInfoGroupFloor(hospitalId),
                staticsDAO.totalDeviceInfoGroupFloor(hospitalId));
    }

    //3、各科室 投放床数量 总订单量
    public List<ItemOrderDeviceStaticsDTO> getTotalDepartInfo(Long hospitalId) {
        return mergeDepartOrderDeviceInfo(hospitalId, staticsDAO.totalOrderInfoGroupDepart(hospitalId),
                staticsDAO.totalDeviceInfoGroupDepart(hospitalId));
    }

    //最近一个月总订单量变化趋势
    public List<OrderLineStaticsDO> totalDayHospitalOrderCountLineLastMonth(Long hospitalId) {
        return staticsDAO.totalDayHospitalOrderCountLineLastMonth(hospitalId);
    }

    //4、各楼层 订单量变化趋势
    public List<OrderLineStaticsDO> totalDayOrderCountLineLastMonthGroupFloor(Long floorId) {
        return staticsDAO.totalDayOrderCountLineLastMonthGroupFloor(floorId);
    }

    //5、各科室 订单量变化趋势
    public List<OrderLineStaticsDO> totalDayOrderCountLineLastMonthGroupDepart(Long departId) {
        return staticsDAO.totalDayOrderCountLineLastMonthGroupDepart(departId);
    }


    private List<ItemOrderDeviceStaticsDTO> mergeHospitalOrderDeviceInfo(List<OrderWdStaticsDO> orderWdStatics, List<DeviceWdStaticsDO> deviceWdStatics) {
        List<HospitalDO> hospitalDOS = hospitalDAO.selectList(new LambdaQueryWrapper<HospitalDO>());
        List<ItemOrderDeviceStaticsDTO> staticsDTOS = new ArrayList<>();
        for (HospitalDO hospitalDO : hospitalDOS) {
            ItemOrderDeviceStaticsDTO staticsDTO = new ItemOrderDeviceStaticsDTO();
            staticsDTO.setShowName(hospitalDO.getHospitalName());
            staticsDTO.setShowId(hospitalDO.getHospitalId());

            if (orderWdStatics != null && orderWdStatics.size() > 0) {
                orderWdStatics.stream()
                        .filter(staticsDO -> hospitalDO.getHospitalId().equals(staticsDO.getShowId()))
                        .findFirst()
                        .ifPresent(staticsDO -> {
                            staticsDTO.setOrderCount(staticsDO.getOrderCount());
                            staticsDTO.setOrderFee(staticsDO.getOrderFee());
                            staticsDTO.setPayFee(staticsDO.getPayFee());
                        });
            }
            if (deviceWdStatics != null && deviceWdStatics.size() > 0) {
                deviceWdStatics.stream()
                        .filter(staticsDO -> hospitalDO.getHospitalId().equals(staticsDO.getShowId()))
                        .findFirst()
                        .ifPresent(staticsDO -> {
                            staticsDTO.setDeviceCount(staticsDO.getDeviceCount());
                        });
            }
            staticsDTOS.add(staticsDTO);
        }

        return staticsDTOS;
    }

    private List<ItemOrderDeviceStaticsDTO> mergeDepartOrderDeviceInfo(Long hospitalId, List<OrderWdStaticsDO> orderWdStatics, List<DeviceWdStaticsDO> deviceWdStatics) {
        List<HospitalDepartDO> buildingDOS = departDAO.selectList(new LambdaQueryWrapper<HospitalDepartDO>()
                .eq(HospitalDepartDO::getHospitalId, hospitalId));
        List<ItemOrderDeviceStaticsDTO> staticsDTOS = new ArrayList<>();
        for (HospitalDepartDO itemDO : buildingDOS) {
            ItemOrderDeviceStaticsDTO staticsDTO = new ItemOrderDeviceStaticsDTO();
            staticsDTO.setShowName(itemDO.getDepartName());
            staticsDTO.setShowId(itemDO.getDepartId());

            if (orderWdStatics != null && orderWdStatics.size() > 0) {
                orderWdStatics.stream()
                        .filter(staticsDO -> itemDO.getDepartId().equals(staticsDO.getShowId()))
                        .findFirst()
                        .ifPresent(staticsDO -> {
                            staticsDTO.setOrderCount(staticsDO.getOrderCount());
                            staticsDTO.setOrderFee(staticsDO.getOrderFee());
                            staticsDTO.setPayFee(staticsDO.getPayFee());
                        });
            }

            if (deviceWdStatics != null && deviceWdStatics.size() > 0) {
                deviceWdStatics.stream()
                        .filter(staticsDO -> itemDO.getDepartId().equals(staticsDO.getShowId()))
                        .findFirst()
                        .ifPresent(staticsDO -> {
                            staticsDTO.setDeviceCount(staticsDO.getDeviceCount());
                        });
            }

            staticsDTOS.add(staticsDTO);
        }

        return staticsDTOS;
    }

    private List<ItemOrderDeviceStaticsDTO> mergeFloorOrderDeviceInfo(Long hospitalId, List<OrderWdStaticsDO> orderWdStatics, List<DeviceWdStaticsDO> deviceWdStatics) {
        List<HospitalBuildingDO> buildingDOS = buildingDAO.selectList(new LambdaQueryWrapper<HospitalBuildingDO>()
                .eq(HospitalBuildingDO::getHospitalId, hospitalId).eq(HospitalBuildingDO::getLevel, 2));
        List<ItemOrderDeviceStaticsDTO> staticsDTOS = new ArrayList<>();
        for (HospitalBuildingDO itemDO : buildingDOS) {
            ItemOrderDeviceStaticsDTO staticsDTO = new ItemOrderDeviceStaticsDTO();
            staticsDTO.setShowName(itemDO.getBuildingName()+"-"+itemDO.getFloorName());
            staticsDTO.setShowId(itemDO.getId());
            if (orderWdStatics != null && orderWdStatics.size() > 0) {
                orderWdStatics.stream()
                        .filter(staticsDO -> itemDO.getId().equals(staticsDO.getShowId()))
                        .findFirst()
                        .ifPresent(staticsDO -> {
                            staticsDTO.setOrderCount(staticsDO.getOrderCount());
                            staticsDTO.setOrderFee(staticsDO.getOrderFee());
                            staticsDTO.setPayFee(staticsDO.getPayFee());
                        });
            }

            if (deviceWdStatics != null && deviceWdStatics.size() > 0) {
                deviceWdStatics.stream()
                        .filter(staticsDO -> itemDO.getId().equals(staticsDO.getShowId()))
                        .findFirst()
                        .ifPresent(staticsDO -> {
                            staticsDTO.setDeviceCount(staticsDO.getDeviceCount());
                        });
            }

            staticsDTOS.add(staticsDTO);
        }

        return staticsDTOS;
    }
}
